package com.xh.bussiness.system.service.impl;

import java.io.Serializable;
import java.util.*;
import java.util.function.IntFunction;
import java.util.stream.Collectors;

import com.xh.bussiness.system.bean.request.UserDataPermissionRequest;
import com.xh.bussiness.system.constant.UserDataCacheConstant;
import com.xh.bussiness.system.model.DictionaryRel;
import com.xh.bussiness.system.model.UserDataPermission;
import com.xh.bussiness.system.service.IDictionaryRelService;
import com.xh.bussiness.system.service.IGroupSubjectService;
import com.xh.bussiness.system.service.IUserDataPermissionService;
import com.xh.core.util.CacheUtils;
import com.xh.core.util.ChineseCharToEnUtil;
import com.xh.core.util.UserUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.jingyou.service.IJYBaseDataService;
import com.xh.bussiness.system.bean.dto.DictionaryBean;
import com.xh.bussiness.system.bean.request.DictionaryRequest;
import com.xh.bussiness.system.dao.DictionaryMapper;
import com.xh.bussiness.system.model.Dictionary;
import com.xh.bussiness.system.service.IDictionaryService;
import com.xh.core.bean.XhPage;
import com.xh.core.service.impl.BaseServiceImpl;
import com.xh.core.util.StringUtils;
import org.springframework.util.CollectionUtils;

/**
 * <p>
 * 数据字典表 服务实现类
 * </p>
 *
 * @author daiwei
 * @since 2018-10-10
 */
@Service
public class DictionaryServiceImpl extends BaseServiceImpl<DictionaryMapper, Dictionary> implements IDictionaryService {

    @Autowired
    private IJYBaseDataService baseDataService;
    @Autowired
    private IDictionaryRelService dictionaryRelService;
    @Autowired
    private IUserDataPermissionService dataPermissionService;
    @Autowired
    private IGroupSubjectService groupSubjectService;

    @Override
    public XhPage queryDictionaryPage(XhPage page, DictionaryRequest bean) {
        QueryWrapper qw = new QueryWrapper<Dictionary>();
        //拼装条件
        qw = prepareParams(bean, qw);
        XhPage xhPage = (XhPage) this.selectPage(page, qw, DictionaryBean.class);
        return xhPage;
    }

    @Override
    public List queryDictionary(DictionaryRequest bean) {
        QueryWrapper<Dictionary> qw = new QueryWrapper<>();
        //拼装条件
        qw = prepareParams(bean, qw);
        qw.orderByAsc("order_no");
        return this.dao.selectList(qw);
    }

    /**
     * 准备条件
     *
     * @param bean
     * @param qw
     */
    private QueryWrapper prepareParams(DictionaryRequest bean, QueryWrapper qw) {
        if (bean.getIds() != null && bean.getIds().length > 0) {
            qw.in("id", bean.getIds());
        }
        if (!StringUtils.isEmpty(bean.getTypeCode())) {
            qw.eq("type_code", bean.getTypeCode().trim());
        }
        if (!StringUtils.isEmpty(bean.getName())) {
            qw.like("name", bean.getName());
        }
//        if(!StringUtils.isEmpty(bean.getParentId())){
//            qw.eq("parent_id",bean.getParentId().trim());
//        }else{
//            if(bean.getParentIds()!=null&&bean.getParentIds().length>0){
//                qw.in("parent_id",bean.getParentIds());
//            }
//        }
		if(null == bean.getStatus()){
			qw.in("status", Arrays.asList(0, 1));
		}else{
			qw.eq("status",bean.getStatus());
		}
        qw.orderByDesc("modify_time");
        qw.orderByAsc("order_no");
        return qw;
    }

    @Override
    public List<Dictionary> queryChilds(String parentType, String parentCode, String childType) {
        return this.dao.queryChilds(parentType, parentCode, childType);
    }

    @Override
    public Map<String, List<Dictionary>> querySubject() throws Exception {
        Map<String, List<Dictionary>> map = new HashMap<String, List<Dictionary>>();
        QueryWrapper<Dictionary> qw = new QueryWrapper<>();
        qw.eq("type_code","GRADE_RANGE");
        qw.eq("status",0);
        List<DictionaryBean> dictionaries = this.selectList(qw,DictionaryBean.class);
        List<String> childCodes = groupSubjectService.queryGroupSubjectCodeByUserId(UserUtils.getCurrentUserId());//查询用户学科权限
        for (DictionaryBean dictionary : dictionaries) {
            String code = dictionary.getCode();
            QueryWrapper<DictionaryRel> qwRel = new QueryWrapper<>();
            qwRel.eq("parent_code",code);
            qwRel.eq("child_type_code","SUBJECT");
            List<DictionaryRel> dictionaryRels = dictionaryRelService.queryByCondition(qwRel);
            List<String> clildCodes = dictionaryRels.stream().map(DictionaryRel::getChildCode).collect(Collectors.toList());
            //取当前年级所有学科 和 用户学科权限的交集
            List<Dictionary> dictionaries1= new ArrayList<>();
            clildCodes.retainAll(childCodes);
            if(clildCodes.size() > 0){
                qw = new QueryWrapper<>();
                qw.eq("type_code","SUBJECT");
                qw.in("code",clildCodes);
                qw.orderByAsc("order_no");
                dictionaries1 = super.queryByCondition(qw);
            }
            map.put(code,dictionaries1);
        }
//        Map<String, List<Dictionary>> result = new LinkedHashMap<>();
//        result.put("primary",map.get("primary"));
//        result.put("middle",map.get("middle"));
//        result.put("high",map.get("high"));
        return map;
    }

    @Override
    public List<Dictionary> queryGrade() throws Exception {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.eq("type_code", "GRADE");
        return super.queryByCondition(qw);
    }

    @Override
    public List<Dictionary> initSubject() throws Exception {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.eq("type_code", "SUBJECT");
        super.deleteByCondition(qw);
        List<Dictionary> subjects = baseDataService.querySubject();
        super.batchInsert(subjects);
        CacheUtils.delete(UserDataCacheConstant.GROUP_DATA_VERSIN_KEY);
        return subjects;
    }

    @Override
    public List<Dictionary> initGrade() throws Exception {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.eq("type_code", "GRADE");
        super.deleteByCondition(qw);
        List<Dictionary> grades = baseDataService.queryGrade();
        super.batchInsert(grades);
        CacheUtils.delete(UserDataCacheConstant.GROUP_DATA_VERSIN_KEY);
        return grades;
    }

    @Override
    public List<Dictionary> queryGradeRange() {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.eq("type_code", "GRADE_RANGE");
        return super.queryByCondition(qw);
    }

    @Override
    public void saveObj(DictionaryBean dictionaryBean) {
        Dictionary dictionary =new Dictionary();
        BeanUtils.copyProperties(dictionaryBean,dictionary);
        if (dictionaryBean.getTypeCode().equals("SUBJECT") && StringUtils.isEmpty(dictionary.getCode())) {
            //学科生成拼音code
            dictionary.setCode(ChineseCharToEnUtil.getPingYin(dictionaryBean.getName()));
        }
        if (dictionaryBean.getTypeCode().equals("TEACH_BOOK_VERSION") || dictionaryBean.getTypeCode().equals("QUES_SOURCE") || dictionaryBean.getTypeCode().equals("QUES_CATEGORY")) {
            String maxBookVersionVal = this.dao.maxDictMaxVal(dictionaryBean.getTypeCode());
            dictionaryBean.setVal(maxBookVersionVal);
        }
        Integer orderNo = this.dao.selectMaxOrderNoByTypeCode(dictionary.getTypeCode());
        dictionary.setOrderNo(orderNo == null ? 0 : orderNo + 1);
        this.insert(dictionary);
        if (StringUtils.isNotEmpty(dictionaryBean.getParentCode())) {
            DictionaryRel dictionaryRel = new DictionaryRel();
            dictionaryRel.setParentTypeCode(dictionaryBean.getParentTypeCode());
            dictionaryRel.setParentCode(dictionaryBean.getParentCode());
            dictionaryRel.setChildTypeCode(dictionary.getTypeCode());
            if (dictionaryBean.getTypeCode().equals("SUBJECT")) {
                dictionaryRel.setChildCode(dictionary.getCode());
            }else{
                dictionaryRel.setChildCode(dictionary.getId());
            }
            dictionaryRelService.insert(dictionaryRel);
        }
    }

    @Override
    public void modifyObj(DictionaryBean dictionaryBean) {
        super.updateObj(dictionaryBean);
        if (StringUtils.isNotEmpty(dictionaryBean.getParentCode())) {
            QueryWrapper<DictionaryRel> qw = new QueryWrapper<>();
            qw.eq("parent_code", dictionaryBean.getParentCode());
            qw.eq("child_code", dictionaryBean.getId());
            dictionaryRelService.deleteByCondition(qw);
            DictionaryRel dictionaryRel = new DictionaryRel();
            dictionaryRel.setParentCode(dictionaryBean.getParentCode());
            dictionaryRel.setChildCode(dictionaryBean.getId());
            dictionaryRelService.insert(dictionaryRel);
        }
        CacheUtils.delete(UserDataCacheConstant.GROUP_DATA_VERSIN_KEY);
    }

    @Override
    public List<DictionaryBean> queryGradeAndSubject(){
        QueryWrapper<Dictionary> qw = new QueryWrapper<>();
        qw.eq("type_code","GRADE_RANGE");
        qw.eq("status",0);
        List<DictionaryBean> dictionaries = this.selectList(qw,DictionaryBean.class);
        for (DictionaryBean dictionary : dictionaries) {
            String code = dictionary.getCode();
            QueryWrapper<DictionaryRel> qwRel = new QueryWrapper<>();
            qwRel.eq("parent_code",code);
            qwRel.eq("child_type_code","SUBJECT");
            List<DictionaryRel> dictionaryRels = dictionaryRelService.queryByCondition(qwRel);
            List<String> clildCodes = dictionaryRels.stream().map(DictionaryRel::getChildCode).collect(Collectors.toList());
            qw = new QueryWrapper<>();
            qw.eq("type_code","SUBJECT");
            qw.in("code",clildCodes);
            qw.orderByAsc("order_no");
            List<DictionaryBean> child = this.selectList(qw,DictionaryBean.class);
            child.forEach(dictionaryBean -> dictionaryBean.setParentCode(code));
            dictionary.setChild(child);
        }
        return dictionaries;
    }

    @Override
    public List<DictionaryBean> queryDataByType(String rangeCode,String typeCode){

        QueryWrapper<DictionaryRel> qwRel = new QueryWrapper<>();
        qwRel.eq("parent_code",rangeCode);
        qwRel.eq("child_type_code",typeCode);

        List<DictionaryRel> dictionaryRels = dictionaryRelService.queryByCondition(qwRel);
        if(CollectionUtils.isEmpty(dictionaryRels)){
            return  new ArrayList<>();
        }
        List<String> clild = dictionaryRels.stream().map(DictionaryRel::getChildCode).collect(Collectors.toList());
        QueryWrapper<Dictionary> qw = new QueryWrapper<>();
        qw.in("id",clild);
        qw.orderByAsc("order_no");
        List<DictionaryBean> child = this.selectList(qw,DictionaryBean.class);

        return child;
    }

    @Override
    public void batchChangeStatus(String[] ids, Integer status) {
        List<Dictionary> dictionaries = super.getDao().selectBatchIds(Arrays.asList(ids));
        if (!CollectionUtils.isEmpty(dictionaries)) {
            for (Dictionary dictionary : dictionaries) {
                dictionary.setStatus(status);
            }
            super.batchUpdate(dictionaries);
        }
        CacheUtils.delete(UserDataCacheConstant.GROUP_DATA_VERSIN_KEY);
    }


    @Override
    public Dictionary queryGradeRangeBySubjectCode(String subjectCode) {
        return this.dao.queryGradeRangeBySubjectCode(subjectCode);
    }

    @Override
    public List<Dictionary> queryDictByTypeCodes(List<String> typeCodes) {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.in("type_code", typeCodes);
        qw.orderByAsc("order_no");
        return super.queryByCondition(qw);
    }

    @Override
    public List<Dictionary> queryDictByCodes(List<String> codes) {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.in("code", codes);
        qw.orderByAsc("order_no");
        return super.queryByCondition(qw);
    }

    @Override
    public Dictionary queryByCode(String code,String typeCode) {
        if (StringUtils.isEmpty(code)) {
            return null;
        }
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.eq("code", code);
        if (!StringUtils.isEmpty(typeCode)) {
            qw.eq("type_code", typeCode);
        }
        qw.eq("deleted",0);
        return this.dao.selectOne(qw);
    }

    @Override
    public List<Dictionary> queryDicByIds(List<String> ids) {
        QueryWrapper<Dictionary> qw = new QueryWrapper<>();
        qw.in("id", ids);
        return this.dao.selectList(qw);
    }

    @Override
    public XhPage<Map<String,Object>> querySubjectPage(XhPage page, String subjectName, String gradeRangeCode) {
        return this.dao.querySubjectPage(page, subjectName, gradeRangeCode);
    }

    @Override
    public List<Dictionary> queryByName(String typeCode, String name) {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.in("type_code", typeCode);
        qw.eq("name",name);
        return super.queryByCondition(qw);
    }

    @Override
    public Dictionary queryFirstByName(String typeCode, String name) {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.in("type_code", typeCode);
        qw.eq("name",name);
        return super.selectFirst(qw);
    }

    @Override
    public Map<String, List<Dictionary>> queryDictByTypeCodesToMap(List<String> typeCodes) {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.in("type_code", typeCodes);
        qw.orderByAsc("order_no");
        List<Dictionary> dictionaries = this.dao.selectList(qw);
        if (!CollectionUtils.isEmpty(dictionaries)) {
            Map<String, List<Dictionary>> datas = dictionaries.stream().collect(Collectors.groupingBy(item -> item.getTypeCode()));
            return datas;
        }
        return new HashMap<>();
    }

    @Override
    public Dictionary queryByTypeAndCode(String typeCode, String code) {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.in("type_code", typeCode);
        qw.eq("code",code);
        return super.selectFirst(qw);
    }

    @Override
    public List<Dictionary> queryByTypeCode(String typeCode) {
        QueryWrapper<Dictionary> qw = new QueryWrapper<Dictionary>();
        qw.in("type_code", typeCode);
        return super.queryByCondition(qw);
    }

    @Override
    public boolean delete(Serializable id) {
        boolean result = super.delete(id);
        CacheUtils.delete(UserDataCacheConstant.GROUP_DATA_VERSIN_KEY);
        return result;
    }

    @Override
    public boolean batchDelete(Serializable[] ids) {
        boolean result = super.batchDelete(ids);
        CacheUtils.delete(UserDataCacheConstant.GROUP_DATA_VERSIN_KEY);
        return result;
    }
}
